﻿using System;
using DiNinject.Repository.Interfaces;
using DiNinject.Web.UI.Models.Person.ModelBuilderInterfaces;

namespace DiNinject.Web.UI.Models.Person.ModelBuilder
{
    public class PersonModelBuilder : IPersonModelBuilder
    {
        #region Initialize
        /// <summary>
        /// Initialize und der ModelContainer wird per Di übergeben.
        /// </summary>
        public PersonModelBuilder(IPersonRespository personRespository)
        {
            if (personRespository == null)
            {
                throw new NullReferenceException("PersonRespository ist Null.");
            }
            _personRespository = personRespository;
        }

        private IPersonRespository _personRespository;
        #endregion

        #region Public Functions
        /// <summary>
        /// Laden aller Personendaten
        /// </summary>
        public PersonListModel LoadAllPersons()
        {
            PersonListModel model = new PersonListModel();
            try
            {
                //abrufen der Personendaten aus der Datenbank
                var persons = _personRespository.AllPersons();

                //Füllen unseres ListModels mit den passenden Personendaten
                foreach (EfModel.Person person in persons)
                {
                    PersonViewModel viewModelPerson = new PersonViewModel();
                    MapPersonViewModel(viewModelPerson, person);
                    model.PersonList.Add(viewModelPerson);
                }

                model.AnzahlAllerAutos = 10;
            }
            catch (Exception exception)
            {
                //TODO Fehlermeldungen kapseln, damit diese entsprechend im View angezeigt werden kann.
            }
            return model;
        }

        /// <summary>
        /// Laden eines leeren ViewModels
        /// </summary>
        public PersonViewModel Load()
        {
            PersonViewModel model = new PersonViewModel();
            try
            {
                model.Alter = 18;
                model.Nachname = string.Empty;
                model.Vorname = string.Empty;
                model.Id = 0;

                //Da Neues Objekt, kann es auch keine Autos haben :-)
                model.AnzahlAutos = 0;
                model.IsAltePerson = model.Alter > 30;
            }
            catch (Exception exception)
            {
                //TODO Fehlermeldungen kapseln, damit diese entsprechend im View angezeigt werden kann.
            }
            return model;
        }

        /// <summary>
        /// Laden einer Person mit der übergebenen PersonenId
        /// </summary>
        /// <param name="personId">Id der Person die geladen werden soll</param>
        public PersonViewModel Load(int personId)
        {
            PersonViewModel model = new PersonViewModel();
            try
            {
                var dbPerson = _personRespository.Load(personId);
                if (dbPerson == null)
                {
                    //TODO Fehlermeldung das die Person nicht gefunden werden konnte.
                    return model;
                }

                MapPersonViewModel(model, dbPerson);
            }
            catch (Exception exception)
            {
                //TODO Fehlermeldungen kapseln, damit diese entsprechend im View angezeigt werden kann.
            }
            return model;
        }

        /// <summary>
        /// Erstellen oder Updaten des übergebenen PersonenEditModels
        /// </summary>
        public PersonViewModel AddOrSavePerson(PersonEditModel editModel)
        {
            PersonViewModel viewModel = new PersonViewModel();
            try
            {
                EfModel.Person person = new EfModel.Person();
                person.Id = editModel.Id;
                person.Nachname = editModel.Nachname;
                person.Vorname = editModel.Vorname;
                person.Benutzername = editModel.Benutzername;
                person.Alter = editModel.Alter;

                var dbPers = _personRespository.AddOrUpdatePerson(person);
                MapPersonViewModel(viewModel, dbPers);
            }
            catch (Exception exception)
            {
                //TODO Fehlermeldungen kapseln, damit diese entsprechend im View angezeigt werden kann.
            }
            return viewModel;
        }
        #endregion

        #region private Functions
        /// <summary>
        /// Mappen unserer DB Person auf das aktuelle ViewModel
        /// </summary>
        /// <param name="viewModel">unser aktuelles ViewModel</param>
        /// <param name="person">DB Personen Objekt</param>
        private void MapPersonViewModel(PersonViewModel viewModel, EfModel.Person person)
        {
            viewModel.Alter = person.Alter;
            viewModel.Nachname = person.Nachname;
            viewModel.Vorname = person.Vorname;
            viewModel.Benutzername = person.Benutzername;
            viewModel.Id = person.Id;
            viewModel.AnzahlAutos = 10;
            viewModel.IsAltePerson = person.Alter > 30;
        }
        #endregion
    }
}